package com.zenithmind.task.pojo.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.zenithmind.common.base.BaseEntity;
import lombok.Data;

import java.util.Objects;

/**
 * 任务附件实体类
 * 遵循面向对象设计原则：
 * 1. 单一职责原则：专注于附件信息管理
 * 2. 封装原则：提供文件操作相关的业务方法
 * 3. 数据完整性：确保文件信息的一致性
 *
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Data
@TableName("task_attachment")
public class TaskAttachment extends BaseEntity {

    /**
     * 附件ID
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;

    /**
     * 任务ID
     */
    @TableField("task_id")
    private String taskId;

    /**
     * 任务标题
     */
    @TableField("task_title")
    private String taskTitle;

    /**
     * 评论ID（如果是评论附件）
     */
    @TableField("comment_id")
    private String commentId;

    /**
     * 文件名
     */
    @TableField("file_name")
    private String fileName;

    /**
     * 原始文件名
     */
    @TableField("original_name")
    private String originalName;

    /**
     * 文件路径
     */
    @TableField("file_path")
    private String filePath;

    /**
     * 文件URL
     */
    @TableField("file_url")
    private String fileUrl;

    /**
     * 文件大小（字节）
     */
    @TableField("file_size")
    private Long fileSize;

    /**
     * 文件类型
     */
    @TableField("file_type")
    private String fileType;

    /**
     * MIME类型
     */
    @TableField("mime_type")
    private String mimeType;

    /**
     * 文件扩展名
     */
    @TableField("file_extension")
    private String fileExtension;

    /**
     * 文件MD5
     */
    @TableField("file_md5")
    private String fileMd5;

    /**
     * 缩略图URL
     */
    @TableField("thumbnail_url")
    private String thumbnailUrl;

    /**
     * 上传者ID
     */
    @TableField("uploader_id")
    private String uploaderId;

    /**
     * 上传者名称
     */
    @TableField("uploader_name")
    private String uploaderName;

    /**
     * 附件类型：1-任务附件，2-评论附件
     */
    @TableField("attachment_type")
    private Integer attachmentType;

    /**
     * 下载次数
     */
    @TableField("download_count")
    private Integer downloadCount;

    /**
     * 是否公开
     */
    @TableField("is_public")
    private Integer isPublic;

    /**
     * 存储位置：1-本地，2-OSS，3-CDN
     */
    @TableField("storage_type")
    private Integer storageType;

    /**
     * 存储桶名称
     */
    @TableField("bucket_name")
    private String bucketName;

    /**
     * 文件描述
     */
    @TableField("description")
    private String description;

    /**
     * 排序权重
     */
    @TableField("sort_order")
    private Integer sortOrder;

    /**
     * 状态：0-删除，1-正常
     */
    @TableField("status")
    private Integer status;

    /**
     * 备注
     */
    @TableField("remark")
    private String remark;

    /**
     * 是否删除：0-删除，1-正常
     */
    @TableField("is_deleted")
    @TableLogic
    private Integer isDeleted;

    // ==================== 业务方法 ====================

    /**
     * 检查是否为任务附件
     *
     * @return 是否为任务附件
     */
    public boolean isTaskAttachment() {
        return attachmentType != null && attachmentType == 1;
    }

    /**
     * 检查是否为评论附件
     *
     * @return 是否为评论附件
     */
    public boolean isCommentAttachment() {
        return attachmentType != null && attachmentType == 2;
    }

    /**
     * 检查是否为图片文件
     *
     * @return 是否为图片文件
     */
    public boolean isImage() {
        if (fileExtension == null) {
            return false;
        }
        String ext = fileExtension.toLowerCase();
        return ext.equals("jpg") || ext.equals("jpeg") || ext.equals("png") ||
               ext.equals("gif") || ext.equals("bmp") || ext.equals("webp");
    }

    /**
     * 检查是否为文档文件
     *
     * @return 是否为文档文件
     */
    public boolean isDocument() {
        if (fileExtension == null) {
            return false;
        }
        String ext = fileExtension.toLowerCase();
        return ext.equals("pdf") || ext.equals("doc") || ext.equals("docx") ||
               ext.equals("xls") || ext.equals("xlsx") || ext.equals("ppt") ||
               ext.equals("pptx") || ext.equals("txt");
    }

    /**
     * 检查是否为压缩文件
     *
     * @return 是否为压缩文件
     */
    public boolean isArchive() {
        if (fileExtension == null) {
            return false;
        }
        String ext = fileExtension.toLowerCase();
        return ext.equals("zip") || ext.equals("rar") || ext.equals("7z") ||
               ext.equals("tar") || ext.equals("gz");
    }

    /**
     * 检查是否为公开文件
     *
     * @return 是否为公开文件
     */
    public boolean isPublic() {
        return isPublic != null && isPublic == 1;
    }

    /**
     * 检查文件状态是否正常
     *
     * @return 状态是否正常
     */
    public boolean isNormal() {
        return status != null && status == 1;
    }

    /**
     * 格式化文件大小
     *
     * @return 格式化后的文件大小
     */
    public String getFormattedFileSize() {
        if (fileSize == null || fileSize <= 0) {
            return "0 B";
        }

        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int unitIndex = 0;
        double size = fileSize.doubleValue();

        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }

        return String.format("%.2f %s", size, units[unitIndex]);
    }

    /**
     * 获取文件类型描述
     *
     * @return 文件类型描述
     */
    public String getFileTypeDescription() {
        if (isImage()) {
            return "图片文件";
        } else if (isDocument()) {
            return "文档文件";
        } else if (isArchive()) {
            return "压缩文件";
        } else {
            return "其他文件";
        }
    }

    /**
     * 检查附件数据有效性
     *
     * @return 是否有效
     */
    public boolean isValid() {
        return taskId != null && !taskId.trim().isEmpty() &&
               fileName != null && !fileName.trim().isEmpty() &&
               filePath != null && !filePath.trim().isEmpty() &&
               fileSize != null && fileSize > 0 &&
               attachmentType != null && (attachmentType == 1 || attachmentType == 2);
    }

    /**
     * 重写 equals 方法
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        if (!super.equals(obj)) return false;

        TaskAttachment that = (TaskAttachment) obj;
        return Objects.equals(id, that.id);
    }

    /**
     * 重写 hashCode 方法
     */
    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), id);
    }
}
